package game.entities;

import game.Game;
import game.InputHandler;
import game.gfx.Colors;
import game.gfx.Font;
import game.gfx.Screen;
import game.level.Level;
import game.net.packets.Packet02Move;

public class Player extends Mob {

	private InputHandler input;
	private int color = Colors.get(-1, 111, 145, 543);
	private int scale = 1;
	protected boolean isSwimming = false;
	private int tickCount = 0;
	private String username;
	private int classType;
	private int maxHealth;
	private int health;
	private boolean isDead;
	private static boolean heldJump = false;

	public Player(Level level, int x, int y, InputHandler input, String username) { // need
																					// to
																					// add
																					// a
																					// health
																					// attribute
																					// here.
		super(level, "Player", x, y, 1);
		this.input = input;
		this.username = username;
		this.health = 200;
		this.maxHealth = 200;
		this.classType = 0;
	}

	public void tick() {
		int xa = 0;
		int ya = 0;
		if (input != null) {
			if (input.up.isPressed()) {
				ya--;
				heldJump = true;
			}else{
				heldJump = false;
			}
			if (input.down.isPressed()) {
				ya++;
			}
			if (input.left.isPressed()) {
				xa--;
			}
			if (input.right.isPressed()) {
				xa++;
			}
		}
		// if(xa != 0 || ya != 0){
		move(xa, ya, true, classType);
		isMoving = true;

		Packet02Move packet = new Packet02Move(this.getUsername(), this.x,
				this.y, this.numSteps, this.isMoving, this.movingDir);
		packet.writeData(Game.game.socketClient);

		// } else {
		isMoving = false;
		// }
		if (!isMoving) {
			// y+=1;
		}
		if (level.getTile(this.x / 8, this.y / 8).getId() == 3) {
			isSwimming = true;
		}
		if (isSwimming && level.getTile(this.x / 8, this.y / 8).getId() != 3) {
			isSwimming = false;
		}
		tickCount++;
	}

	public void render(Screen screen) {
		int xTile = 0;
		int yTile = 28;
		int walkingSpeed = 4;
		int flipTop = (numSteps >> walkingSpeed) & 1;
		int flipBottom = (numSteps >> walkingSpeed) & 1;

		if (movingDir == 1) {
			xTile = 0;
		} else if (movingDir > 1) {
			xTile += 4 + ((numSteps >> walkingSpeed) & 1) * 2;
			flipTop = (movingDir - 1) % 2;
		}

		int modifier = 8 * scale;
		int xOffset = x - modifier / 2;
		int yOffset = y - modifier / 2 - 4;
		if (isSwimming) {
			int waterColor = 0;
			yOffset += 4;
			if (tickCount % 60 < 15) {
				waterColor = Colors.get(-1, -1, 225, -1);
			} else if (15 <= tickCount % 60 && tickCount % 60 < 30) {
				yOffset -= 1;
				waterColor = Colors.get(-1, 225, 115, -1);
			} else if (30 <= tickCount % 60 && tickCount % 60 < 45) {
				waterColor = Colors.get(-1, 115, -1, 225);
			} else {
				yOffset -= 1;
				waterColor = Colors.get(-1, 225, 115, -1);
			}
			screen.render(xOffset, yOffset + 3, 0 + 27 * 32, waterColor, 0x00,
					1);
			screen.render(xOffset + 8, yOffset + 3, 0 + 27 * 32, waterColor,
					0x01, 1);
		}
		screen.render(xOffset + modifier - (modifier * flipTop), yOffset, xTile
				+ 1 + yTile * 32, color, flipTop, scale);
		screen.render(xOffset + (modifier * flipTop), yOffset, (xTile) + yTile
				* 32, color, flipTop, scale);

		//Heart rendering
		if ((double) (maxHealth / health) >= 1 && (double) (maxHealth / health) < 2) {
		screen.render(xOffset + 4, yOffset + 17, 31 + 29 * 32,
				Colors.get(-1, 300, 500, 555), 0x00, scale);
		} else if ((double) (maxHealth / health) >= 2 && (double) (maxHealth / health) < 3) {
		screen.render(xOffset + 4, yOffset + 17, 31 + 29 * 32,
				Colors.get(-1, 200, 400, 444), 0x00, scale);
		} else if ((double) (maxHealth / health) >= 3 && (double) (maxHealth / health) < 4) {
		screen.render(xOffset + 4, yOffset + 17, 31 + 29 * 32,
				Colors.get(-1, 100, 300, 333), 0x00, scale);
		} else {
		screen.render(xOffset + 4, yOffset + 17, 31 + 29 * 32,
				Colors.get(-1, 000, 200, 222), 0x00, scale);
		}

		if (!isSwimming) {
			screen.render(xOffset + modifier - (modifier * flipBottom), yOffset
					+ modifier, xTile + 1 + (yTile + 1) * 32, color,
					flipBottom, scale);
			screen.render(xOffset + (modifier * flipBottom),
					yOffset + modifier, (xTile) + (yTile + 1) * 32, color,
					flipBottom, scale);
		}
		if (username != null) {
			String usernamehp = username + " - " +  health;
			Font.render(usernamehp, screen, xOffset - (usernamehp.length() - 1) / 2
					* 8, yOffset - 10, Colors.get(-1, -1, -1, 555), 1);
		}
	}

	public boolean hasCollided(int xa, int ya) {
		int xMin = 0;
		int xMax = 7;
		int yMin = 3;
		int yMax = 7;
		for (int x = xMin; x < xMax; x++) {
			if (isSolidTile(xa, ya, x, yMin)) {
				return true;
			}
		}
		for (int x = xMin; x < xMax; x++) {
			if (isSolidTile(xa, ya, x, yMax)) {
				return true;
			}
		}
		for (int y = yMin; y < yMax; y++) {
			if (isSolidTile(xa, ya, xMin, y)) {
				return true;
			}
		}
		for (int y = yMin; y < yMax; y++) {
			if (isSolidTile(xa, ya, xMax, y)) {
				return true;
			}
		}
		return false;
	}

	public String getUsername() {
		return this.username;
	}
	
	public static boolean getHeldJump(){
		return heldJump;
	}

	public boolean isOnGround() {
		int xMin = 0;
		int xMax = 7;
		int yMin = 3;
		int yMax = 7;
		for (int x = xMin; x < xMax; x++) {
			if (hasCollided(0, 1)) {
				return true;
			}
		}
		return false;
	}

	public void takeDamage(int dmg) {
		health -= dmg;
		// health -= (dmg - defense); would be a way to do def. could also pass
		// in a boolean shouldDefend, for armor piercing attacks.
		if (health <= dmg) {
			isDead = true;
		} else {
			isDead = false;
		}
	}
}
